package com.xinyi.reactivemvvmkt.sources.repository

import com.xinyi.httpdemo.model.ResponseData
import com.xinyi.reactivemvvmkt.model.Resource
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn

/**
 * @author 杨耿雷
 * @date 2024/9/24 21:26
 * @description 数据仓库基类，用于统一处理接口回调的数据流向
 */
abstract class BaseRepository {

    /**
     * 安全地调用远程 API，处理加载状态和错误。
     *
     * @param T API调用返回的数据类型。
     * @param apiCall 一个挂起函数，代表要执行的 API 调用。
     *
     * @return Flow<Resource<T>> 返回包含资源状态的数据流，可能是加载中、成功或失败。
     * <p>
     * 调用此方法时会发射三个不同状态
     * @see Resource.Loading 加载中状态
     * @see Resource.Success 请求成功状态 （包含成功的数据）
     * @see Resource.Fail 请求失败状态 （包含错误信息或异常）
     */
    suspend fun <T> safeRemoteApiCall(apiCall: suspend () -> ResponseData): Flow<Resource<T>> = flow {
        emit(Resource.Loading)  // 发出加载状态
        val response = apiCall() // 执行 API 调用
        if (response.isSuccess && (response.code == 0 || response.code == 200)) {
            emit(Resource.Success(response.data as T)) // 发出成功结果
        } else {
            emit(Resource.Fail(java.io.IOException(response.message))) // 发出失败信息
        }
    }.catch { ex ->
        ex.printStackTrace() // 打印异常堆栈
        emit(Resource.Fail(ex)) // 发出失败信息
    }.flowOn(Dispatchers.IO) // 在 IO 线程上执行流
}